﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.ServiceProcess;
using System.Text;
using System.Threading;

namespace SystemDownLoadService
{
    public partial class Service1 : ServiceBase
    {
        public Service1()
        {
            InitializeComponent();
        }

        protected bool start = false;

        protected TcpListener Listener;

        protected Thread WorkMain;

        protected Thread Monitor;

        protected override void OnStart(string[] args)
        {
            try
            {
                start = true;
                Monitor = new Thread(new ThreadStart(Monit));
                Monitor.Start();
            }
            catch (Exception ex)
            {
            }
        }

        protected void Monit()
        {
            while (start)
            {
                if (WorkMain == null)
                {
                    WorkMain = new Thread(new ThreadStart(Listen));
                    WorkMain.Start();
                }
                if (WorkMain.ThreadState == System.Threading.ThreadState.Aborted ||
                    WorkMain.ThreadState == System.Threading.ThreadState.Stopped)
                {
                    WorkMain = new Thread(new ThreadStart(Listen));
                    WorkMain.Start();
                }
                Thread.Sleep(5000);
            }
        }

        protected void Listen()
        {
            int Port = 0;
            if (int.TryParse(ConfigurationManager.AppSettings["Port"], out Port))
            {
                try
                {
                    TcpClient client = null;
                    Listener = new TcpListener(Port);
                    Listener.Start(1024);
                    while (start)
                    {
                        client = Listener.AcceptTcpClient();
                        ThreadPool.QueueUserWorkItem(DownLoad, client);

                    }
                    Listener.Stop();
                }
                catch (System.ArgumentOutOfRangeException ex)
                {
                    throw new Exception("初始化监听器失败", ex);
                }
            }
            else
            {
                throw new Exception("配置信息加载错误");
            }
        }

        protected void DownLoad(object State)
        {
            using (TcpClient client = State as TcpClient)
            {
                try
                {
                    client.ReceiveTimeout = 2000;

                    NetworkStream Ns = client.GetStream();
                    List<byte> cmddata = new List<byte>();
                    int bytedata=-1;
                    while ((bytedata = Ns.ReadByte()) > -1)
                    {
                        cmddata.Add((byte)bytedata);
                    }
                    DownUtil.DownRequest Request = new DownUtil.DownRequest();
                    Request.UnSerialize(cmddata.ToArray());
                    Logger.WriteEntry(Request.Url, EventLogEntryType.Information);
                    if (authentic(Request))
                    {
                        Ns.WriteByte((byte)0);
                        DownFile(Request.Url, Ns);
                    }
                    else
                    {
                        Ns.WriteByte((byte)1);
                        Ns.Flush();
                        Ns.Close();
                        client.Close();
                    }
                }
                catch (Exception ex)
                {
                    lock (Logger)
                    {
                        Logger.WriteEntry("下载执行出错:" + ex.Message, EventLogEntryType.Error);
                    }
                }
                finally
                {
                    client.Close();
                }

            }
        }

        protected void DownFile(string Url, NetworkStream Ns)
        {
            try
            {
                bool firstread = true;
                WebRequest request = HttpWebRequest.Create(Url);
                Stream Fs = request.GetRequestStream();
                byte[] buffer = new byte[2048];
                int ReadCount = 0;
                while ((ReadCount = Fs.Read(buffer, 0, 2048)) > 0)
                {
                    if (firstread)
                    {
                        Ns.WriteByte((byte)0);
                        Ns.Flush();
                        firstread = false;
                    }
                    Ns.Write(buffer, 0, ReadCount);
                }
                Ns.Flush();
            }
            catch (Exception ex)
            {
                Ns.WriteByte((byte)1);
                Ns.Flush();
                lock (Logger)
                {
                    Logger.WriteEntry("访问远程资源出错:" + ex.Message, EventLogEntryType.Error);
                }
            }
        }

        protected bool authentic(DownUtil.DownRequest request)
        {
            return true;
        }

        protected override void OnStop()
        {  
            start = false; 
        }
    }
}
